<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Carbon\Carbon;

class MembershipCode extends Model
{
    use HasFactory;

    protected $fillable = [
        'code',
        'type',
        'duration',
        'is_used',
        'used_by',
        'used_at',
        'expires_at',
        'description',
        'effective_start_at',
        'effective_end_at',
    ];

    protected $casts = [
        'is_used' => 'boolean',
        'used_at' => 'datetime',
        'expires_at' => 'datetime',
        'effective_start_at' => 'datetime',
        'effective_end_at' => 'datetime',
    ];

    /**
     * 会员类型配置
     */
    public static $membershipTypes = [
        'day' => ['name' => '日卡', 'duration' => 1],
        'month' => ['name' => '月卡', 'duration' => 30],
        'year' => ['name' => '年卡', 'duration' => 365],
        'permanent' => ['name' => '永久卡', 'duration' => null],
    ];

    /**
     * 使用者关联
     */
    public function user()
    {
        return $this->belongsTo(User::class, 'used_by');
    }

    /**
     * 生成兑换码
     */
    public static function generateCode($type, $expiresAt = null)
    {
        if (!array_key_exists($type, self::$membershipTypes)) {
            throw new \InvalidArgumentException('Invalid membership type');
        }

        $code = strtoupper(Str::random(16));
        $duration = self::$membershipTypes[$type]['duration'];

        return self::create([
            'code' => $code,
            'type' => $type,
            'duration' => $duration,
            'expires_at' => $expiresAt,
        ]);
    }

    /**
     * 使用兑换码
     */
    public function redeem(User $user)
    {
        if ($this->is_used) {
            throw new \Exception('兑换码已被使用');
        }

        if ($this->expires_at && $this->expires_at->isPast()) {
            throw new \Exception('兑换码已过期');
        }

        // 计算新的会员到期时间
        $currentExpiry = $user->membership_expires_at ? Carbon::parse($user->membership_expires_at) : Carbon::now();
        $effectiveStart = Carbon::now();
        $effectiveEnd = null;
        
        if ($this->type === 'permanent') {
            $newExpiry = null; // 永久会员
            $effectiveEnd = null; // 永久会员无结束时间
        } else {
            // 如果当前会员还未过期，则在当前到期时间基础上延长
            if ($currentExpiry->isFuture()) {
                $newExpiry = $currentExpiry->addDays($this->duration);
                $effectiveStart = $currentExpiry; // 从当前会员到期时间开始生效
            } else {
                $newExpiry = Carbon::now()->addDays($this->duration);
                $effectiveStart = Carbon::now(); // 立即生效
            }
            $effectiveEnd = $newExpiry;
        }

        // 更新用户会员信息
        $user->update([
            'membership_expires_at' => $newExpiry,
            'membership_type' => $this->type,
        ]);

        // 标记兑换码为已使用，并记录生效时间段
        $this->update([
            'is_used' => true,
            'used_by' => $user->id,
            'used_at' => Carbon::now(),
            'effective_start_at' => $effectiveStart,
            'effective_end_at' => $effectiveEnd,
        ]);

        return $newExpiry;
    }

    /**
     * 检查兑换码是否有效
     */
    public function isValid()
    {
        return !$this->is_used && (!$this->expires_at || $this->expires_at->isFuture());
    }

    /**
     * 获取会员类型名称
     */
    public function getTypeNameAttribute()
    {
        return self::$membershipTypes[$this->type]['name'] ?? $this->type;
    }
    
    /**
     * 获取会员类型名称（方法形式）
     */
    public function getTypeName()
    {
        return self::$membershipTypes[$this->type]['name'] ?? $this->type;
    }
    
    /**
     * 获取兑换码状态名称
     */
    public function getStatusName()
    {
        if ($this->is_used) {
            return 'success';
        }
        
        if ($this->expires_at && $this->expires_at->isPast()) {
            return 'expired';
        }
        
        return 'failed';
    }
}